package com.challenge.Action;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.challenge.App;
import com.challenge.Constants.IConstants;
import com.challenge.Kitchen.Kitchen;
import com.challenge.Order.Order;
import com.challenge.Shelf.BaseShelf;
import com.challenge.Shelf.Shelf;
import com.challenge.Shelf.TrashCan;
import com.challenge.util.FormateString;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * place orders
 * receive an order every quarter second, make the order (instant), then place
 * the order on its correct shelf.
 */
public class PlaceOrderProcess {

    public static int count = 1;//order Counter
    public static double orderAge_time = 0;// order init time

    /**
     * place the order on its correct shelf.
     * There are four types of shelves:
     * ● A hot shelf that can store 15 hot orders
     * ● A cold shelf that can store 15 cold orders
     * ● A frozen shelf that can store 15 frozen orders
     * ● An overflow shelf that can store 20 of any order
     * When the hot, cold, or frozen shelves are full, orders can be placed on the overflow shelf. If all
     * the shelves including the overflow shelf are full then an order should be removed and
     * considered waste.
     */
    public Order processOrders(JSONArray jsonArray, int i, Kitchen kitchen, double counter)throws Exception{
        JSONObject jsonObject = jsonArray.getJSONObject(i);
        Order order = (Order)jsonObject.toJavaObject(Order.class);

        order.setOrderAge(counter);

        BaseShelf shelf = kitchen.getShelfContent().getContent().get(order.getTemp());
        BaseShelf trashCan = kitchen.getShelfContent().getContent().get(IConstants.TRASH);
        BaseShelf overFlowShelf = kitchen.getShelfContent().getContent().get(IConstants.OVERFLOW);
        if(shelf.checkFull()){
            if(overFlowShelf.checkFull()) {
                trashCan.getStore().add(order);
            }else{
                order.setShelfType(IConstants.OVERFLOW);
                overFlowShelf.getStore().add(order);
                kitchen.getSortShelf().store.add(order);
            }
        }else{
            order.setShelfType(order.getTemp());
            shelf.getStore().add(order);
            kitchen.getSortShelf().store.add(order);
        }

        return order;
    }

    // receive an order every quarter second
    public void placeOrder(JSONArray ordersArray,Kitchen kitchen){
        System.out.println("receive an order every quarter second , place the order on its correct shelf ========>");

        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Date date = new Date(System.currentTimeMillis() + 3600 * 1000);
                DateFormat dFormat_ss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                String formatDate = dFormat_ss.format(date);

                if (count <= ordersArray.size()) {
                    Order order = null;
                    try {
                        order = processOrders(ordersArray, count - 1, kitchen,orderAge_time);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(formatDate + " " + FormateString.padRight(String.valueOf(count),2," ") + " order | " + "Name : " + FormateString.padRight(order.getName(),25," ") + " Shelf : " + FormateString.padRight(order.getShelfType(),9," ") + " orderInitAge : " + order.getOrderAge() + "  ShelfLife :" + order.getShelfLife());
                    orderAge_time = orderAge_time + 0.25; // receive an order every quarter second
                    count++;
                } else {
                    App.flag = false;
                    executorService.shutdown();
                }
            }
        }, 0, 250, TimeUnit.MILLISECONDS);

    }


}
